﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Configuration;
using System.Web.Http;
using System.Web.Http.ModelBinding;

namespace ProjBackEnd.Lib
{
    /// <summary>
    /// 
    /// </summary>
    public class DataUtil
    {
        /// <summary>
        /// 检索手机白名单
        /// 白名单内的手机号，不受发送频率、发送次数限制，主要用于调试及管理
        /// </summary>
        /// <param name="_mobile">待验证的手机号</param>
        /// <returns>true-在白名单；false-不在白名单内</returns>
        public static bool CheckMobileWhitelist(string _mobile)
        {
            if (!System.Text.RegularExpressions.Regex.IsMatch(_mobile, @"^[1][34578]\d{9}$")) return false;
            List<string> lstMobileWhitelist = new List<string>();
            string strMobilelist = WebConfigurationManager.AppSettings["MobileWhitelist"].ToString();
            string[] strsMobile = strMobilelist.Split(';');
            foreach (string _strMobileWhite in strsMobile)
            {
                if (_mobile == _strMobileWhite) return true;
            }
            return false;
        }

        /// <summary>
        /// 写系统日志
        /// </summary>
        /// <param name="_strCatalog">日志分类</param>
        /// <param name="_strContent">日志内容</param>
        public static void WriteLog(string _strCatalog, string _strContent)
        {
            try
            {
                string strFilename = "SysLog" + DateTime.Today.ToString("yyMMdd") + ".txt";
                if (!File.Exists(HttpContext.Current.Request.PhysicalApplicationPath + "Logs\\" + strFilename)) File.Create(HttpContext.Current.Request.PhysicalApplicationPath + "Logs\\" + strFilename).Close();
                FileStream fs = new FileStream(HttpContext.Current.Request.PhysicalApplicationPath + "Logs\\" + strFilename, FileMode.Append);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + " " + _strCatalog + " : " + _strContent);
                sw.Flush();
                sw.Close();
                fs.Close();
                Thread.Sleep(20);
            }
            catch(Exception ex)
            {
                return;
            }
        }

        public static string Base64StringToImage(string _strBase64str, string _strFilePath)
        {
            string strFilename = "";
            try
            {
                if (!Directory.Exists(_strFilePath)) Directory.CreateDirectory(_strFilePath);
                byte[] b = Convert.FromBase64String(_strBase64str);
                MemoryStream ms = new MemoryStream(b);
                Image img = Image.FromStream(ms);
                strFilename = Guid.NewGuid().ToString("N") + ".jpg";

                while (File.Exists(_strFilePath + strFilename))
                {
                    strFilename = Guid.NewGuid().ToString("N") + ".jpg";
                }

                img.Save(_strFilePath + strFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
                ms.Close();
            }
            catch (Exception ex)
            {
                strFilename = "";
                WriteLog("Base64StringToImage", ex.Message);
            }
            return strFilename;
        }

        #region  密码加密

        [DllImport("des64.dll")]
        private static extern void b64_des(StringBuilder in_str, StringBuilder out_str, string key, int lenth, uint option);
        [DllImport("des64.dll")]
        private static extern int b64_size(int lenth, uint option);

        /// <summary>
        /// 密码加密核心方法
        /// </summary>
        /// <param name="_strPassSource">密码明文</param>
        /// <returns></returns>
        public static string EncryptPassword(string _strPassSource)
        {
            string strKey = "proj+group+user-pwd";
            string strPassEncrypt = _strPassSource;

            int iOutlen = b64_size(_strPassSource.Length, 1);
            StringBuilder sbSource = new StringBuilder(_strPassSource);
            StringBuilder sbPassEncypt = new StringBuilder();
            sbPassEncypt.Capacity = iOutlen;
            sbPassEncypt.Length = iOutlen;
            b64_des(sbSource, sbPassEncypt, strKey, _strPassSource.Length, 1);
            strPassEncrypt = sbPassEncypt.ToString().Trim();
            return strPassEncrypt;
        }

        #endregion

        #region 参数混淆

        private static string PRIVITE_KEY = "e6d64a3d844356f9";
        private static string AREA = "ecI1tPsXxo9nipbRNWYV68rLEjgHa0qMld732wBuDzvJ4AKZUfO5hTQSGCkymF|";
        public enum enumDeEncryptType
        {
            Decrypt, Encrypt
        }

        /// <summary>
        /// 参数混淆算法
        /// </summary>
        /// <param name="_strOriginalStr">原始字符串</param>
        /// <param name="_accType">加密/解密</param>
        /// <returns></returns>
        public static string PlaintextConfusion(string _strOriginalStr, enumDeEncryptType _accType)
        {
            string strRet = "";
            for (int i = 0; i < _strOriginalStr.Length; i++)
            {
                string strSingle = _strOriginalStr.Substring(i, 1);
                int offset = GetOffsetWithKeyModel(i);
                string strResultLetter = "";
                if (AREA.Contains(strSingle)) //仅处理混淆区间包含的字符
                {
                    for (int j = 0; j < AREA.Length; j++)
                    {
                        if (strSingle == AREA.Substring(j, 1))
                        {
                            int iTemp = 0;
                            if (_accType == enumDeEncryptType.Encrypt) //****Encrypt
                            {
                                iTemp = (j + offset) % AREA.Length;
                            }
                            //***************Decrypt****************************
                            else if (_accType == enumDeEncryptType.Decrypt)
                            {
                                iTemp = j - offset;
                                if (iTemp < 0) { iTemp = (int)AREA.Length + iTemp; }
                            }
                            //****************************************************
                            strResultLetter = AREA.Substring(iTemp, 1);
                        }
                    }
                }
                else
                {
                    strResultLetter = strSingle;
                }
                strRet += strResultLetter;
            }
            return strRet;
        }

        private static int GetOffsetWithKeyModel(int _iIndex)
        {
            int keyModel = _iIndex % PRIVITE_KEY.Length;
            char[] c = PRIVITE_KEY.Substring(keyModel, 1).ToCharArray();
            int offset = c[0];
            if (offset >= '0' && offset <= '9') offset -= 48;
            else if (offset >= 'A' && offset <= 'Z') offset -= 55;
            else if (offset >= 'a' && offset <= 'z') offset -= 61;

            return offset;
        }

        #endregion

        /// <summary>
        /// 根据数据源判定所属地区电话区号
        /// 此区号拼接到业务员联系电话上，以区别地区
        /// </summary>
        /// <param name="_strDatasour">数据源</param>
        /// <returns>电话区号</returns>
        public static string GetAreanoByDatasour(string _strDatasour)
        {
            string strRet = "";
            switch (_strDatasour.ToUpper())
            {
                case "PROJ":
                    strRet = "0532-";
                    break;
                default:
                    break;
            }
            return strRet;
        }

        public static string GetModelStateError(ModelStateDictionary _modelState)
        {
            string strReturn = "";
            List<string> lstKeys = _modelState.Keys.ToList();
            foreach (string key in lstKeys)
            {
                List<ModelError> lstErrs = _modelState[key].Errors.ToList();
                foreach (ModelError err in lstErrs)
                {
                    if (err.ErrorMessage != "") strReturn = err.ErrorMessage;
                    else strReturn = err.Exception.Message;
                    break;
                }
                if (strReturn != "") break;
            }
            return strReturn;
        }

        public static string CheckTokenValid(HttpRequestMessage _request)
        {
            if (!_request.Headers.Contains("token") || _request.Headers.GetValues("token") == null)
                return "";
            else
                return _request.Headers.GetValues("token").ToList()[0];
        }

        /// <summary>
        /// 检查Token是否存在
        /// </summary>
        /// <param name="_request"></param>
        /// <param name="_strToken"></param>
        /// <returns></returns>
        public static bool CheckTokenExist(HttpRequestMessage _request, out string _strToken)
        {
            //****前端适配后修改此逻辑
            _strToken = "123";
            return true;
            //if (!_request.Headers.TryGetValues("token", out IEnumerable<string> lstValues))
            //{
            //    _strToken = "";
            //    return false;
            //}
            //_strToken = lstValues.ToList()[0];
            //return true;
        }

        /// <summary>  
        /// Json反序列化  
        /// </summary>  
        /// <typeparam name="T">对象类型</typeparam>  
        /// <param name="_strJson">反序列化json字符串</param>  
        /// <returns></returns>  
        public static T JsonDeserialize<T>(string _strJson)
        {
            try
            {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(_strJson));
                T t = (T)ser.ReadObject(ms);
                return t;
            }
            catch(Exception ex)
            {
                WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message + "@" + _strJson);
                return default(T);
            }
        }

        /// <summary>  
        /// Json序列化  
        /// </summary>  
        /// <typeparam name="T">对象类型</typeparam>  
        /// <param name="t">序列化对象</param>  
        /// <returns></returns>  
        public static string JsonSerializer<T>(T t)
        {
            var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
            return JsonConvert.SerializeObject(t, Formatting.Indented, jsonSetting);
        }

    }
}